/*
 * Copyright (C) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.facebook.fresco.helper.photoview.anim;

import ohos.aafwk.ability.Ability;
import ohos.aafwk.content.Intent;
import ohos.agp.animation.Animator;
import ohos.agp.components.Component;
import ohos.agp.components.ComponentContainer;
import ohos.agp.components.Image;
import ohos.agp.utils.Point;
import ohos.agp.utils.Rect;
import ohos.agp.window.service.Display;
import ohos.agp.window.service.DisplayManager;
import ohos.app.dispatcher.TaskDispatcher;

import com.facebook.drawee.drawable.ScalingUtils;
import com.facebook.drawee.generic.GenericDraweeHierarchy;
import com.facebook.fresco.helper.photoview.MViewPager;
import com.facebook.fresco.helper.photoview.PhotoDraweeView;
import com.facebook.fresco.helper.utils.MLog;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Optional;

/**
 * 过渡兼容
 *
 * @author dev
 * @since 2021-08-02
 */
public class TransitionCompat {
    private static int mInterpolator = Animator.CurveType.ACCELERATE;
    private static final long DURATION = 300;
    private static long mAnimTime = DURATION;
    private Ability mAbility;
    private ArrayList<ViewOptions> mViewOptions;
    private int mCurrentPosition;
    private AnimListener mAnimListener;
    private MViewPager mViewPager;

    /**
     * 过渡兼容
     *
     * @param activity 活动
     */
    public TransitionCompat(final Ability activity) {
        mAbility = activity;
        Intent bundle = activity.getIntent();
        assert bundle != null;
        mViewOptions = bundle.getSerializableParam(ViewOptionsCompat.KEY_VIEW_OPTION_LIST);
    }

    /**
     * 设置当前位置
     *
     * @param currentPosition 当前位置
     */
    public void setCurrentPosition(int currentPosition) {
        this.mCurrentPosition = currentPosition;
    }

    /**
     * 开始转变
     */
    public void startTransition() {
        ViewOptions viewOptions = mViewOptions.get(mCurrentPosition);
        if (viewOptions == null
            || viewOptions.getThumbnail() == null
            || !viewOptions.isInTheScreen()
            || !viewOptions.isVerticalScreen()) {
            return;
        }
        thumbnailScaleUpAnimation(viewOptions, true);
    }

    /**
     * 完成后过渡
     *
     */
    public void finishAfterTransition() {
        ViewOptions viewOptions = mViewOptions.get(mCurrentPosition);
        if (viewOptions != null
            && viewOptions.isInTheScreen()
            && viewOptions.isVerticalScreen()) {
            // 照片墙中的View，在屏幕上是可见的并且当前的屏幕是竖屏，才会有动画效果
            thumbnailScaleUpAnimation(viewOptions, false);
        } else {
            mAbility.terminateAbility();
            mAbility.setTransitionAnimation(0, 0);
        }
    }

    private void thumbnailScaleUpAnimation(ViewOptions viewOptions, final boolean isEnter) {
        if (isEnter) {
            startThumbnailAnimation(viewOptions);
        } else {
//            endThumbnailAnimation(viewOptions); // 结束动画有bug
        }

        // 执行屏幕的动画
        scaleUpAnimation(viewOptions, isEnter);
    }

    private Image getThumbnailOriginalImageView(ViewOptions viewOptions) {
        if (viewOptions == null || viewOptions.getThumbnail() == null) {
            return null;
        }
        PhotoDraweeView draweeView = new PhotoDraweeView(mAbility);
        GenericDraweeHierarchy hierarchy = draweeView.getHierarchy();
        hierarchy.setActualImageScaleType(ScalingUtils.ScaleType.FIT_XY);
        draweeView.setHierarchy(hierarchy);
        draweeView.setImageURI(viewOptions.getThumbnail());
        return draweeView;
    }

    /**
     * 开始缩略图动画
     *
     * @param viewOptions 视图选项
     */
    private void startThumbnailAnimation(ViewOptions viewOptions) {
        final Image bitmapImageView = getThumbnailOriginalImageView(viewOptions);
        if (bitmapImageView == null) {
            return;
        }

        bitmapImageView.setVisibility(Component.INVISIBLE);

        /*
         * 设定view开始时的大小和坐标位置
         */
        ComponentContainer.LayoutConfig orginalParams =
            new ComponentContainer.LayoutConfig(viewOptions.getWidth(), viewOptions.getHeight());
        ComponentContainer rootView = getRoot(mAbility);
        if (rootView != null) {
            rootView.addComponent(bitmapImageView, orginalParams);
        }
        bitmapImageView.setTranslationX(viewOptions.getStartX());
        bitmapImageView.setTranslationY(viewOptions.getStartY());

        Optional<Display> display = DisplayManager.getInstance().getDefaultDisplay(mAbility);
        Point pt = new Point();
        display.get().getSize(pt);

        float fraction = 0.8f;
        final Rect finalBounds = new Rect(0, 0,
            (int) (display.get().getAttributes().width * fraction),
            (int) (display.get().getAttributes().height * fraction));

        mAnimListener = new AnimListener(bitmapImageView, null);
        final ViewAnim anim = new ViewAnim();
        anim.setDuration((long) (mAnimTime * fraction));
        anim.setTimeInterpolator(mInterpolator);
        anim.addAnimListener(mAnimListener);
        TaskDispatcher uiTaskDispatcher = mAbility.getUITaskDispatcher();
        uiTaskDispatcher.asyncDispatch(new Runnable() {

            @Override
            public void run() {
                anim.startViewSimpleAnim(bitmapImageView, finalBounds, 0, 0, 1f, 0f);
            }
        });
    }

    /**
     * 缩略图动画结束
     *
     * @param viewOptions 视图选项
     */
    private void endThumbnailAnimation(ViewOptions viewOptions) {
        final Image bitmapImageView = getThumbnailOriginalImageView(viewOptions);
        if (bitmapImageView == null) {
            return;
        }

        bitmapImageView.setVisibility(Component.INVISIBLE);
        // 获取屏幕宽度跟高度
        Optional<Display> display = DisplayManager.getInstance().getDefaultDisplay(mAbility);
        Point pt = new Point();
        display.get().getSize(pt);
        /*
         * 设定view开始时的大小和坐标位置
         */
        ComponentContainer.LayoutConfig orginalParams =
            new ComponentContainer.LayoutConfig(display.get().getAttributes().width,
                display.get().getAttributes().height);

        ComponentContainer rootView = getRoot(mAbility);
        rootView.addComponent(bitmapImageView, orginalParams);
        bitmapImageView.setTranslationX(0);
        bitmapImageView.setTranslationY(0);


        final Rect finalBounds = new Rect(viewOptions.getStartX(), viewOptions.getStartY(),
            viewOptions.getStartX() + viewOptions.getWidth(),
            viewOptions.getStartY() + viewOptions.getHeight());

        mAnimListener = new AnimListener(bitmapImageView, null);
        final ViewAnim anim = new ViewAnim();
        anim.setDuration(mAnimTime);
        anim.setTimeInterpolator(mInterpolator);
        anim.addAnimListener(mAnimListener);

        TaskDispatcher uiTaskDispatcher = mAbility.getUITaskDispatcher();
        uiTaskDispatcher.asyncDispatch(new Runnable() {

            @Override
            public void run() {
                anim.startViewSimpleAnim(bitmapImageView, finalBounds, 0, 0, 0f, 1f);
            }
        });
    }

    private ComponentContainer getRoot(Ability context) {
        try {
            Class<?> clz = context.getWindow().getClass();

            Field declaredField = clz.getDeclaredField("agpWindow");
            declaredField.setAccessible(true);
            Object window = declaredField.get(context.getWindow());

            Class<?> windowClz = window.getClass();
            Field declaredField1 = windowClz.getDeclaredField("mWindowRoot");
            declaredField1.setAccessible(true);

            return (ComponentContainer) declaredField1.get(window);
        } catch (NoSuchFieldException | IllegalAccessException error) {
            MLog.error("TransitionCompat getRoot NoSuchFieldException | IllegalAccessException " + error.getLocalizedMessage());
        }
        return null; // 返回空
    }

    private void scaleUpAnimation(ViewOptions viewOptions, final boolean isEnter) {
        if (!viewOptions.isInTheScreen()) {
            return;
        }

        if (viewOptions.isVerticalScreen() != ViewOptionsCompat.isVerticalScreen(mAbility)) {
            return;
        }

        final SceneScaleUpAnimator anim = new SceneScaleUpAnimator(mAbility, mViewPager,viewOptions);
        anim.setAnimInterpolator(mInterpolator);
        anim.setAnimDuration(mAnimTime);
        TaskDispatcher uiTaskDispatcher = mAbility.getUITaskDispatcher();
        uiTaskDispatcher.asyncDispatch(new Runnable() {
            @Override
            public void run() {
                anim.playScreenAnim(isEnter);
            }
        });
    }

    /**
     * 设置父视图
     *
     * @param mViewPager m视图寻呼机
     */
    public void setParentView(MViewPager mViewPager) {
        this.mViewPager = mViewPager;
    }
}
